package com.hhh.springai_test.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhh.springai_test.common.ErrorCode;
import com.hhh.springai_test.constant.UserConstant;
import com.hhh.springai_test.exception.BusinessException;
import com.hhh.springai_test.mapper.CommentMapper;
import com.hhh.springai_test.model.dto.comment.AddCommentDTO;
import com.hhh.springai_test.model.dto.comment.QueryCommentDTO;
import com.hhh.springai_test.model.dto.comment.SimpleQueryCommentDTO;
import com.hhh.springai_test.model.dto.comment.UpdateCommentDTO;
import com.hhh.springai_test.model.dto.commentreply.QueryCommentReplyDTO;
import com.hhh.springai_test.model.po.Comment;
import com.hhh.springai_test.model.po.User;
import com.hhh.springai_test.model.vo.CommentReplyVO;
import com.hhh.springai_test.model.vo.CommentVO;
import com.hhh.springai_test.model.vo.UserVo;
import com.hhh.springai_test.service.*;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 29915
* @description 针对表【comment(评论表)】的数据库操作Service实现
* @createDate 2025-02-06 09:28:13
*/
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment>
    implements CommentService {

    @Resource
    private UserService userService;

    @Resource
    private BookService bookService;

    @Resource
    private CommunityPostService communityPostService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private CommentReplyService commentReplyService;

    private static final String COMMENT_LOCK_KEY = "comment:lock:";
    private static final String COMMENT_COUNT_KEY = "comment:count:";

    @Override
    public Long addComment(AddCommentDTO addCommentDTO, Long userId) {
        // 参数校验
        if (addCommentDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 获取锁
        String lockKey = COMMENT_LOCK_KEY + userId;
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 5, TimeUnit.SECONDS);
        if (Boolean.FALSE.equals(lock)) {
            throw new BusinessException(ErrorCode.BUSY_ERROR, "操作太频繁");
        }

        try {
            // 检查一分钟内的评论次数
            String countKey = COMMENT_COUNT_KEY + userId + ":" + addCommentDTO.getTargetId();
            Integer count = (Integer) redisTemplate.opsForValue().get(countKey);
            if (count != null && count >= 3) {
                throw new BusinessException(ErrorCode.BUSY_ERROR, "评论次数超限");
            }
            Integer targetType = addCommentDTO.getTargetType();
            //判断这个targetType是否不等于1和0如果是就报错
            if (targetType != 0 && targetType != 1) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论类型不正确");
            }
            // 创建评论
            Comment comment = new Comment();
            if(targetType == 0){
                if (bookService.getById(addCommentDTO.getTargetId()) == null) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "书籍不存在");
                }
                comment.setUserid(userId);
                comment.setTargetid(addCommentDTO.getTargetId());
                comment.setTargettype(addCommentDTO.getTargetType());
                comment.setContent(addCommentDTO.getContent());
                comment.setCommenttime(new Date());
            }else{
                if(communityPostService.getById(addCommentDTO.getTargetId()) == null){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "帖子不存在");
                }
                comment.setUserid(userId);
                comment.setTargetid(addCommentDTO.getTargetId());
                comment.setTargettype(addCommentDTO.getTargetType());
                comment.setContent(addCommentDTO.getContent());
                comment.setCommenttime(new Date());
            }
            // 保存评论
            boolean success = this.save(comment);
            if (!success) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论保存失败");
            }
            // 更新评论计数
            if (count == null) {
                redisTemplate.opsForValue().set(countKey, 1, 1, TimeUnit.MINUTES);
            } else {
                redisTemplate.opsForValue().increment(countKey);
            }

            return comment.getId();
        } finally {
            // 释放锁
            redisTemplate.delete(lockKey);
        }
    }

    @Override
    public boolean deleteComment(Long id, Long userId) {
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 校验评论是否存在
        Comment comment = this.getById(id);
        if (comment == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"评论不存在");
        }

        // 仅评论作者和管理员可删除
        User user = userService.getById(userId);
        if (!userId.equals(comment.getUserid()) && !user.getUserRole().equals(UserConstant.ADMIN_ROLE)) {
            throw new BusinessException(ErrorCode.NOT_AUTH_CODE, "你没有权限删除此条帖子");
        }

        return this.removeById(id);
    }

    @Override
    public boolean updateComment(UpdateCommentDTO updateCommentDTO, Long userId) {
        if (updateCommentDTO == null || updateCommentDTO.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 校验评论是否存在
        Comment comment = this.getById(updateCommentDTO.getId());
        if (comment == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论不存在");
        }

        // 仅评论作者和管理员可修改
        User user = userService.getById(userId);
        if (!userId.equals(comment.getUserid()) && !user.getUserRole().equals(UserConstant.ADMIN_ROLE)) {
            throw new BusinessException(ErrorCode.NOT_AUTH_CODE, "你没有权限修改这条帖子");
        }
        Comment updateComment = new Comment();
        BeanUtils.copyProperties(comment, updateComment);
        updateComment.setContent(updateCommentDTO.getContent());
        return this.updateById(updateComment);
    }

    @Override
    public Page<CommentVO> queryCommentPage(QueryCommentDTO queryCommentDTO) {
        if (queryCommentDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        // 只有当 targetId 和 targetType 都不为空时才添加条件
        if (queryCommentDTO.getTargetId() != null && queryCommentDTO.getTargetType() != null) {
            queryWrapper.eq(Comment::getTargetid, queryCommentDTO.getTargetId())
                       .eq(Comment::getTargettype, queryCommentDTO.getTargetType());
        }
        // 内容模糊查询
        queryWrapper.like(StringUtils.isNotBlank(queryCommentDTO.getContent()), 
                         Comment::getContent, 
                         queryCommentDTO.getContent());
        queryWrapper.orderByDesc(Comment::getCreatetime);

        // 获取分页大小，默认为10
        long pageSize = queryCommentDTO.getPageSize() != null ? queryCommentDTO.getPageSize() : 10;
        Page<Comment> commentPage = this.page(new Page<>(queryCommentDTO.getCurrent(), pageSize), queryWrapper);
        
        // 转换为VO
        Page<CommentVO> commentVOPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        List<CommentVO> commentVOList = commentPage.getRecords().stream().map(comment -> {
            CommentVO commentVO = new CommentVO();
            BeanUtils.copyProperties(comment, commentVO);
            
            // 获取用户信息
            User user = userService.getById(comment.getUserid());
            if (user != null) {
                UserVo userVo = new UserVo();
                BeanUtils.copyProperties(user, userVo);
                commentVO.setUserInfo(userVo);
            }
            
            // 获取评论回复列表
            QueryCommentReplyDTO queryCommentReplyDTO = new QueryCommentReplyDTO();
            queryCommentReplyDTO.setCommentId(comment.getId());
            queryCommentReplyDTO.setCurrent(1L);
            queryCommentReplyDTO.setPageSize(999L); // 设置一个合理的回复数量限制
            Page<CommentReplyVO> replyVOPage = commentReplyService.queryCommentReplyPage(queryCommentReplyDTO);
            commentVO.setCommentReplies(replyVOPage.getRecords());
            
            return commentVO;
        }).collect(Collectors.toList());
        
        commentVOPage.setRecords(commentVOList);
        return commentVOPage;
    }

    @Override
    public Page<CommentVO> queryCommentSimplePage(SimpleQueryCommentDTO simpleQueryCommentDTO) {
        if (simpleQueryCommentDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        // 只有当 targetId 和 targetType 都不为空时才添加条件
        if (simpleQueryCommentDTO.getTargetType() != null) {
            queryWrapper.eq(Comment::getTargettype, simpleQueryCommentDTO.getTargetType());
        }
        // 内容模糊查询
        queryWrapper.like(StringUtils.isNotBlank(simpleQueryCommentDTO.getContent()),
                Comment::getContent,
                simpleQueryCommentDTO.getContent());
        queryWrapper.orderByDesc(Comment::getCreatetime);

        // 获取分页大小，默认为10
        long pageSize = simpleQueryCommentDTO.getPageSize() != null ? simpleQueryCommentDTO.getPageSize() : 10;
        Page<Comment> commentPage = this.page(new Page<>(simpleQueryCommentDTO.getCurrent(), pageSize), queryWrapper);

        // 转换为VO
        Page<CommentVO> commentVOPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        List<CommentVO> commentVOList = commentPage.getRecords().stream().map(comment -> {
            CommentVO commentVO = new CommentVO();
            BeanUtils.copyProperties(comment, commentVO);

            // 获取用户信息
            User user = userService.getById(comment.getUserid());
            if (user != null) {
                UserVo userVo = new UserVo();
                BeanUtils.copyProperties(user, userVo);
                commentVO.setUserInfo(userVo);
            }

            // 获取评论回复列表
            QueryCommentReplyDTO queryCommentReplyDTO = new QueryCommentReplyDTO();
            queryCommentReplyDTO.setCommentId(comment.getId());
            queryCommentReplyDTO.setCurrent(1L);
            queryCommentReplyDTO.setPageSize(999L); // 设置一个合理的回复数量限制
            Page<CommentReplyVO> replyVOPage = commentReplyService.queryCommentReplyPage(queryCommentReplyDTO);
            commentVO.setCommentReplies(replyVOPage.getRecords());

            return commentVO;
        }).collect(Collectors.toList());

        commentVOPage.setRecords(commentVOList);
        return commentVOPage;
    }
}




